package org.br.erp.base.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.br.erp.base.entity.Material;
import org.br.erp.base.entity.Scmbillofmaterial;
import org.br.erp.base.entity.Scmbillofmaterialitem;
import org.br.erp.base.entity.Scmcobillofmaterial;
import org.br.erp.base.mapper.ScmbillofmaterialitemMapper;
import org.br.erp.base.mapper.ScmbillofmaterialMapper;
import org.br.erp.base.mapper.ScmcobillofmaterialMapper;
import org.br.erp.base.service.IMaterialService;
import org.br.erp.base.service.IScmbillofmaterialService;
import org.br.erp.base.utils.ERPUtils;
import org.br.erp.base.vo.MaterialVo;
import org.br.erp.base.vo.ScmbillofMaterialImportVo;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import java.io.Serializable;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Description: 物料清单
 * @Author: jeecg-boot
 * @Date:   2022-11-30
 * @Version: V1.0
 */
@Service
public class ScmbillofmaterialServiceImpl extends ServiceImpl<ScmbillofmaterialMapper, Scmbillofmaterial> implements IScmbillofmaterialService {

	@Autowired
	private ScmbillofmaterialMapper scmbillofmaterialMapper;
	@Autowired
	private ScmbillofmaterialitemMapper scmbillofmaterialitemMapper;

	@Autowired
	private ScmcobillofmaterialMapper scmcobillofmaterialMapper;

	@Autowired
	private IMaterialService materialService;

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void saveMain(Scmbillofmaterial scmbillofmaterial, List<Scmbillofmaterialitem> scmbillofmaterialitemList, List<Scmcobillofmaterial> scmcobillofmaterials) {

		if(scmbillofmaterial.getBillcode()==null || scmbillofmaterial.getBillcode().equalsIgnoreCase("")){
			MaterialVo materialVo = materialService.getMaterialVoInfoByMaterialID(scmbillofmaterial.getMaterialid());

			scmbillofmaterial.setBillcode(materialVo.getMaterialname()+"物料请单" );
		}
		scmbillofmaterialMapper.insert(scmbillofmaterial);

		String materialid = scmbillofmaterial.getMaterialid();
		Material material = materialService.getById(materialid);
		if(material.getIsbomflag() == null || material.getIsbomflag().equalsIgnoreCase("0")){
			material.setIsbomflag("1");
			materialService.updateById(material);
		}

		if(scmbillofmaterialitemList!=null && scmbillofmaterialitemList.size()>0) {
			for(Scmbillofmaterialitem entity:scmbillofmaterialitemList) {
				if(ERPUtils.isNoneOrEmpty(entity.getMaterialid())){
					continue;
				}
				//外键设置
				entity.setParentid(scmbillofmaterial.getId());

				scmbillofmaterialitemMapper.insert(entity);
			}
		}
		if(scmcobillofmaterials!=null && scmcobillofmaterials.size()>0){
			for (Scmcobillofmaterial scmcobillofmaterial : scmcobillofmaterials) {
				scmcobillofmaterial.setParentid(scmbillofmaterial.getId());
				scmcobillofmaterialMapper.insert(scmcobillofmaterial);
			}
		}
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void updateMain(Scmbillofmaterial scmbillofmaterial,List<Scmbillofmaterialitem> scmbillofmaterialitemList,List<Scmcobillofmaterial> scmcobillofmaterialList) {
		scmbillofmaterialMapper.updateById(scmbillofmaterial);
		
		//1.先删除子表数据
		scmbillofmaterialitemMapper.deleteByMainId(scmbillofmaterial.getId());

		scmcobillofmaterialMapper.deleteByMainId(scmbillofmaterial.getId());
		
		//2.子表数据重新插入
		if(scmbillofmaterialitemList!=null && scmbillofmaterialitemList.size()>0) {
			for(Scmbillofmaterialitem entity:scmbillofmaterialitemList) {
				//外键设置
				entity.setParentid(scmbillofmaterial.getId());
				scmbillofmaterialitemMapper.insert(entity);
			}
		}

		if(scmcobillofmaterialList!=null && scmcobillofmaterialList.size()>0){
			for (Scmcobillofmaterial entity : scmcobillofmaterialList) {
				entity.setParentid(scmbillofmaterial.getId());
				scmcobillofmaterialMapper.insert(entity);
			}
		}
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void delMain(String id) {
		Scmbillofmaterial scmbillofmaterial = scmbillofmaterialMapper.selectById(id);
		Material material = materialService.getById(scmbillofmaterial.getMaterialid());
		if(material!=null){
			String isbomflag = material.getIsbomflag();
			if(material.getIsbomflag()!=null && material.getIsbomflag().equalsIgnoreCase("0")){
			}else{
				material.setIsbomflag("0");
				materialService.updateById(material);

			}
		}

		scmbillofmaterialitemMapper.deleteByMainId(id);
		scmbillofmaterialMapper.deleteById(id);
		scmcobillofmaterialMapper.deleteByMainId(id);
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void delBatchMain(Collection<? extends Serializable> idList) {
		for(Serializable id:idList) {
			scmbillofmaterialitemMapper.deleteByMainId(id.toString());
			scmbillofmaterialMapper.deleteById(id);
		}
	}

	@Override
	public List<Scmbillofmaterialitem> getBomInfoByItemid(String partentMaterialid) {
		QueryWrapper<Scmbillofmaterial> queryWrapper=new QueryWrapper<>();
		queryWrapper.eq("materialid",partentMaterialid);
		List<Scmbillofmaterial> scmbillofmaterials = scmbillofmaterialMapper.selectList(queryWrapper);
		if(scmbillofmaterials!=null && scmbillofmaterials.size()>0){
			Scmbillofmaterial scmbillofmaterial = scmbillofmaterials.get(0);
			List<Scmbillofmaterialitem> scmbillofmaterialitems = scmbillofmaterialitemMapper.selectByMainId(scmbillofmaterial.getId());
			return scmbillofmaterialitems;
		}else{
			throw new RuntimeException("不存在物料清单，请重新配置！");
		}
	}

	@Override
	public List<Scmbillofmaterial> getBomInfoByMaterialId(String materialid) {
		QueryWrapper<Scmbillofmaterial> queryWrapper=new QueryWrapper<>();
		queryWrapper.eq("materialid",materialid);
		List<Scmbillofmaterial> scmbillofmaterials = scmbillofmaterialMapper.selectList(queryWrapper);
		return scmbillofmaterials;
	}

	@Override
	public List<JSONObject> getBomInfoByParentMaterialId(String materialId) {
		List<JSONObject> res=new ArrayList<>();
		//todo 先获取父物料数据
		List<Scmbillofmaterial> bomInfoByMaterialId = getBomInfoByMaterialId(materialId);
		//如果有多个，先去获取版本最高的一个

		bomInfoByMaterialId.sort(Comparator.comparing(Scmbillofmaterial::getVersion).reversed());

		if(bomInfoByMaterialId.size()==0){
			throw new RuntimeException("未查找到物料清单");
		}

		//得到父物料
		Scmbillofmaterial scmbillofmaterial = bomInfoByMaterialId.get(0);

		//查找当前分录
		List<Scmbillofmaterialitem> scmbillofmaterialitems = scmbillofmaterialitemMapper.selectByMainId(scmbillofmaterial.getId());

		for (Scmbillofmaterialitem scmbillofmaterialitem : scmbillofmaterialitems) {
			JSONObject curObject=new JSONObject();
			curObject.put("materialid",scmbillofmaterialitem.getMaterialid());
			curObject.put("qty",scmbillofmaterialitem.getFzqty().divide(scmbillofmaterialitem.getFmqty()));
			curObject.put("suppletype",scmbillofmaterialitem.getSuppletype());

			res.add(curObject);

			if(!ERPUtils.isNoneOrEmpty(scmbillofmaterialitem.getChildBomId())){
				String childBomId = scmbillofmaterialitem.getChildBomId();
				getChildBomInfoByParent(childBomId,res);
			}
		}
		return res;
	}

	@Override
	@Transactional
	public void importMaterialFromExcel(List<ScmbillofMaterialImportVo> importVos) {
		if(importVos.size() == 0){
			throw new RuntimeException("导入数据不正确");
		}

		Map<String, List<ScmbillofMaterialImportVo>> mainMaterial = importVos.stream().collect(Collectors.groupingBy(item -> item.getMainmateriealcode()));

		for (String mainMaterialcode : mainMaterial.keySet()) {

			Scmbillofmaterial scmbillofmaterial=new Scmbillofmaterial();
			scmbillofmaterial.setBillcode(mainMaterialcode+"清单");
			scmbillofmaterial.setBomoftype("EBOM");
			scmbillofmaterial.setBomyt("TY");
			scmbillofmaterial.setBomtype("BZBOM");

			MaterialVo materialVo = materialService.getMaterialVoInfoByMaterialcode(mainMaterialcode);
			if(materialVo==null){
				throw new RuntimeException("当前物料编号："+mainMaterialcode+"不存在，请检查物料定义");
			}

			scmbillofmaterial.setMaterialid(materialVo.getId());
			scmbillofmaterial.setModel(materialVo.getModel());
			scmbillofmaterial.setSpecs(materialVo.getMspecs());
			scmbillofmaterial.setCompanyid(ERPUtils.getCurCompanyid());
			scmbillofmaterial.setVersion(1);
			scmbillofmaterial.setIsenable("0");

			scmbillofmaterialMapper.insert(scmbillofmaterial);

			List<ScmbillofMaterialImportVo> scmbillofMaterialImportVos = mainMaterial.get(mainMaterialcode);

			for (ScmbillofMaterialImportVo itemEntity : scmbillofMaterialImportVos) {

				Scmbillofmaterialitem scmbillofmaterialitem=new Scmbillofmaterialitem();
				scmbillofmaterialitem.setParentid(scmbillofmaterial.getId());
				MaterialVo itemMaterialVo = materialService.getMaterialVoInfoByMaterialcode(itemEntity.getItemmaterialcode());
				if(itemMaterialVo==null){
					throw new RuntimeException("当前物料编号"+itemEntity.getItemmaterialcode()+"不存在，请检查物料定义");
				}
				scmbillofmaterialitem.setMaterialid(itemMaterialVo.getId());
				scmbillofmaterialitem.setMaterialcode(itemMaterialVo.getMaterialcode());
				scmbillofmaterialitem.setMaterialname(itemMaterialVo.getMaterialname());
				scmbillofmaterialitem.setModel(itemMaterialVo.getModel());
				scmbillofmaterialitem.setMspecs(itemMaterialVo.getMspecs());
				scmbillofmaterialitem.setChildBomId("");
				scmbillofmaterialitem.setUomid(itemMaterialVo.getUom());
				scmbillofmaterialitem.setFmqty(BigDecimal.valueOf(1));
				scmbillofmaterialitem.setFzqty(ERPUtils.getBigDecimal(itemEntity.getItemqty()));
				scmbillofmaterialitem.setGdshl(BigDecimal.ZERO);
				scmbillofmaterialitem.setGdshl(BigDecimal.ZERO);
				scmbillofmaterialitem.setSuppletype("ZZ");
				scmbillofmaterialitem.setMchildtype("BZJ");

				scmbillofmaterialitemMapper.insert(scmbillofmaterialitem);
			}

		}
	}

	@Override
	public List<Scmbillofmaterialitem> getBillOfMaterialItem(String materialid) {
		LambdaQueryWrapper<Scmbillofmaterialitem> queryWrapper=new LambdaQueryWrapper<>();
		queryWrapper.eq(Scmbillofmaterialitem::getMaterialid,materialid);
		List<Scmbillofmaterialitem> scmbillofmaterialitems = scmbillofmaterialitemMapper.selectList(queryWrapper);
		return scmbillofmaterialitems;
	}

	@Override
	public List<JSONObject> getParentOfBom(String materialId) {

		QueryWrapper<Scmbillofmaterial> scmbillofmaterialQueryWrapper=new QueryWrapper<>();
		scmbillofmaterialQueryWrapper.exists("select 1 from Scmbillofmaterialitem where parentid = scmbillofmaterial.id and Scmbillofmaterialitem.materialid = '"+materialId+"'");
		List<Scmbillofmaterial> scmbillofmaterials = scmbillofmaterialMapper.selectList(scmbillofmaterialQueryWrapper);

		List<JSONObject> res=new ArrayList<>();

		for (Scmbillofmaterial scmbillofmaterial : scmbillofmaterials) {
			JSONObject curRes= new JSONObject();
			QueryWrapper<Scmbillofmaterialitem> queryWrapper=new QueryWrapper<>();
			queryWrapper.eq("parentid",scmbillofmaterial.getId());
			queryWrapper.eq("materialid",materialId);
			List<Scmbillofmaterialitem> scmbillofmaterialitems = scmbillofmaterialitemMapper.selectList(queryWrapper);

			if(scmbillofmaterialitems.size() == 0){
				continue;
			}

			Scmbillofmaterialitem scmbillofmaterialitem = scmbillofmaterialitems.get(0);
			BigDecimal fzqty = scmbillofmaterialitem.getFzqty();
			BigDecimal fmqty = scmbillofmaterialitem.getFmqty();
			BigDecimal multiply = BigDecimal.ONE.divide(fzqty,6, RoundingMode.HALF_UP).multiply(fmqty);
			curRes.put("materialid",scmbillofmaterial.getMaterialid());
			curRes.put("id",scmbillofmaterial.getId());
			Material material = materialService.getById(scmbillofmaterial.getMaterialid());
			if(material!=null) {
				curRes.put("materialcode", material.getMaterialcode());
				curRes.put("model", material.getModel());
				curRes.put("specs", material.getMspecs());
				curRes.put("materialname",material.getMaterialname());
			}
			curRes.put("fzqty",multiply);
			curRes.put("fmqty","1");
			curRes.put("hasChild","1");
			curRes.put("level","-1");

			res.add(curRes);
		}

		return res;
	}

	private List<JSONObject> getChildBomInfoByParent(String bomid,List<JSONObject> res){
		Scmbillofmaterial scmbillofmaterial = scmbillofmaterialMapper.selectById(bomid);
		if(scmbillofmaterial==null){
			return res;
		}
		List<Scmbillofmaterialitem> scmbillofmaterialitems = scmbillofmaterialitemMapper.selectByMainId(bomid);
		if(scmbillofmaterialitems.size() == 0){
			return res;
		}
		for (Scmbillofmaterialitem scmbillofmaterialitem : scmbillofmaterialitems) {
			JSONObject curObject=new JSONObject();
			curObject.put("materialid",scmbillofmaterialitem.getMaterialid());
			curObject.put("qty",scmbillofmaterialitem.getFzqty().divide(scmbillofmaterialitem.getFmqty()));
			curObject.put("suppletype",scmbillofmaterialitem.getSuppletype());
			res.add(curObject);
			getChildBomInfoByParent(scmbillofmaterialitem.getChildBomId(),res);
		}

		return res;
	}





}
